import json
import base64
import os
from typing import Dict, Any, Union


class ConfigManager:
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(ConfigManager, cls).__new__(cls)
        return cls._instance

    @staticmethod
    def convert_to_base64_config(config_file_path: str, output_file_path: str = None) -> str:
        """
        读取普通配置文件，转换为存储有base64数据的配置文件
        
        Args:
            config_file_path: 原始配置文件路径
            output_file_path: 输出文件路径，默认为原始文件名+_base64.json
            
        Returns:
            str: 输出文件路径
        """
        
        def image_to_base64(image_path):
            """将图片文件转换为base64编码"""
            with open(image_path, "rb") as image_file:
                return base64.b64encode(image_file.read()).decode('utf-8')

        # 读取原始配置文件
        with open(config_file_path, "r", encoding="utf-8") as f:
            config = json.load(f)

        # 转换main_images
        new_main_images = []
        for path in config["main_images"]:
            filename = os.path.basename(path)
            try:
                data = image_to_base64(path)
                new_main_images.append({
                    "filename": filename,
                    "data": data,
                    # 添加base64标识位
                    "is_base64": True
                })
            except FileNotFoundError:
                print(f"警告: 找不到文件 {path}")

        # 转换detail_images
        new_detail_images = []
        for path in config["detail_images"]:
            filename = os.path.basename(path)
            try:
                data = image_to_base64(path)
                new_detail_images.append({
                    "filename": filename,
                    "data": data,
                    # 添加base64标识位
                    "is_base64": True
                })
            except FileNotFoundError:
                print(f"警告: 找不到文件 {path}")

        # 转换sku_images
        new_sku_images = []
        for item in config["sku_images"]:
            path = item["path"]
            filename = os.path.basename(path)
            try:
                data = image_to_base64(path)
                new_sku_images.append({
                    "filename": filename,
                    "data": data,
                    "price": item["price"],
                    "code": item["code"],
                    # 添加base64标识位
                    "is_base64": True
                })
            except FileNotFoundError:
                print(f"警告: 找不到文件 {path}")

        # 更新配置对象
        config["main_images"] = new_main_images
        config["detail_images"] = new_detail_images
        config["sku_images"] = new_sku_images

        # 确定输出文件路径
        if output_file_path is None:
            base_name = os.path.splitext(config_file_path)[0]
            output_file_path = f"{base_name}_base64.json"

        # 写入新配置文件
        with open(output_file_path, "w", encoding="utf-8") as f:
            json.dump(config, f, ensure_ascii=False, indent=4)

        return output_file_path

    @staticmethod
    def load_config(config_file_path: str, extract_base64: bool = True) -> Dict[str, Any]:
        """
        读取json文件，判断是否有base64数据，如果有则释放到本地并返回json数据
        
        Args:
            config_file_path: 配置文件路径
            extract_base64: 是否提取base64数据到本地文件
            
        Returns:
            Dict[str, Any]: 配置数据
        """
        
        def base64_to_image(base64_data, image_path):
            """将base64编码数据转换为图片文件"""
            with open(image_path, "wb") as image_file:
                image_file.write(base64.b64decode(base64_data))

        # 读取配置文件
        with open(config_file_path, "r", encoding="utf-8") as f:
            config = json.load(f)

        # 检查是否存在base64数据
        has_base64_data = False
        if "main_images" in config and len(config["main_images"]) > 0:
            if isinstance(config["main_images"][0], dict) and "is_base64" in config["main_images"][0]:
                has_base64_data = True

        # 如果没有base64数据，直接返回
        if not has_base64_data:
            return config

        # 如果不提取base64数据，直接返回
        if not extract_base64:
            return config

        # 创建保存图片的目录
        image_dir = "extracted_images"
        os.makedirs(image_dir, exist_ok=True)

        # 转换main_images
        new_main_images = []
        for item in config["main_images"]:
            filename = item["filename"]
            image_path = os.path.join(image_dir, filename)
            try:
                base64_to_image(item["data"], image_path)
                # 使用绝对路径
                new_main_images.append(os.path.abspath(image_path))
            except Exception as e:
                print(f"警告: 无法保存图片 {filename}: {e}")

        # 转换detail_images
        new_detail_images = []
        for item in config["detail_images"]:
            filename = item["filename"]
            image_path = os.path.join(image_dir, filename)
            try:
                base64_to_image(item["data"], image_path)
                # 使用绝对路径
                new_detail_images.append(os.path.abspath(image_path))
            except Exception as e:
                print(f"警告: 无法保存图片 {filename}: {e}")

        # 转换sku_images
        new_sku_images = []
        for item in config["sku_images"]:
            filename = item["filename"]
            image_path = os.path.join(image_dir, filename)
            try:
                base64_to_image(item["data"], image_path)
                # 使用绝对路径
                new_sku_images.append({
                    "path": os.path.abspath(image_path),
                    "price": item["price"],
                    "code": item["code"]
                })
            except Exception as e:
                print(f"警告: 无法保存图片 {filename}: {e}")

        # 更新配置对象
        config["main_images"] = new_main_images
        config["detail_images"] = new_detail_images
        config["sku_images"] = new_sku_images

        # 写入新的配置文件
        base_name = os.path.splitext(config_file_path)[0]
        output_file_path = f"{base_name}_restored.json"
        with open(output_file_path, "w", encoding="utf-8") as f:
            json.dump(config, f, ensure_ascii=False, indent=4)

        return config
    

# import rich

# ConfigManager.convert_to_base64_config(config_file_path="./config.json",output_file_path="newconfig.json")

# s = ConfigManager.load_config("newconfig.json")
# rich.print(s)